package com.orcamento.service;

import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;

import com.orcamento.entity.enums.Month;
import com.orcamento.entity.report.CategoryReport;
import com.orcamento.entity.report.GeneralBalanceReport;
import com.orcamento.entity.report.HeritageReport;
import com.orcamento.entity.report.OverviewReport;
import com.orcamento.entity.report.Report;
import com.orcamento.entity.report.EventReport;
import com.orcamento.entity.report.ReportBuilder;
import com.orcamento.service.filter.ListFilter;
import com.orcamento.util.CalendarUtil;

public class ReportService {

	@Autowired
	private transient GainService gainService;
	@Autowired
	private transient SpentService spentService;
	@Autowired
	private transient FundService fundService;
	@Autowired
	private transient EventService eventService;
	@Autowired
	private transient CategoryService categoryService;

	public OverviewReport overview(Integer year, Month month, Long accountId) {
		month = month != null ? month : Month.findById( CalendarUtil.getCurrentMonth() );
		year = year != null ? year : CalendarUtil.getCurrentYear();
		
		DateTime start = CalendarUtil.toDate(1, month.id, year, 0, 0, 0);
		DateTime limit = CalendarUtil.toDate(month.maxDays, month.id, year, 23, 59, 59);
		
		return (OverviewReport) ReportBuilder.newInstance()
										.withType( ReportBuilder.OVERVIEW_REPORT )
										.withGains( gainService.findBetween(start, limit, accountId) )
										.withSpents( spentService.findBetween(start, limit, accountId) )
										.withFunds( fundService.findUntil(year, month, accountId) )
										.build(year, month);
	}
	
	public GeneralBalanceReport generalBalance(Integer year, Month month, Long accountId) {
		return (GeneralBalanceReport) ReportBuilder.newInstance()
										.withType( ReportBuilder.GENERAL_BALANCE_REPORT )
										.withGains( gainService.findByFilter(ListFilter.ALL, accountId) )
										.withSpents( spentService.findByFilter(ListFilter.ALL, accountId) )
										.withEvents( eventService.findAll(accountId) )
										.withCategories( categoryService.findAll(accountId) )
										.build(year, month);
	}

	public CategoryReport categories(Integer year, Month month, Long accountId) {
		return (CategoryReport) ReportBuilder.newInstance()
										.withType( ReportBuilder.CATEGORY_REPORT )
										.withCategories( categoryService.findAll(accountId) )
										.build(year, month);
	}

	public Report events(Integer year, Month month, Long accountId) {
		return (EventReport) ReportBuilder.newInstance()
										.withType( ReportBuilder.EVENT_REPORT )
										.withEvents( eventService.findAll(accountId) )
										.build(year, month);
	}

	public Report heritage(Integer year, Month month, Long accountId) {
		return (HeritageReport) ReportBuilder.newInstance()
									.withType( ReportBuilder.HERITAGE_REPORT )
									.withEvents( eventService.findAll(accountId) )
									.withFunds( fundService.findAll(accountId) )
									.build(year, month);
	}

}
